﻿using System;
using System.ComponentModel;
using System.Diagnostics;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
namespace JGSY.LP.Controls
{
    /// <summary>
    /// MonitoringDashboard.xaml 的交互逻辑
    /// </summary>
    public partial class MonitoringDashboard : UserControl
    {

        // 控件构造函数
        public MonitoringDashboard()
        { 
            // 初始化组件
            InitializeComponent();
            // 注册大小改变事件处理程序
            this.SizeChanged += MonitoringDashboard_SizeChanged;
        }
        /// <summary>
        /// 控件大小改变事件处理方法
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void MonitoringDashboard_SizeChanged(object sender, SizeChangedEventArgs e)
        {
            // 计算宽高中的最小值，确保仪表为正方形
            double minSize = Math.Min(this.RenderSize.Width, this.RenderSize.Height);
            this.backEllipse.Width = minSize;
            this.backEllipse.Height = minSize;
        }

        // 依赖属性，依赖对象
        // 仪表盘背景画刷属性
        public Brush PlateBackground
        {
            get { return (Brush)GetValue(PlateBackgroundProperty); }
            set { SetValue(PlateBackgroundProperty, value); }
        }
        // 注册仪表盘背景画刷依赖属性，提供默认值
        public static readonly DependencyProperty PlateBackgroundProperty =
            DependencyProperty.Register("PlateBackground", typeof(Brush), typeof(MonitoringDashboard), new PropertyMetadata(default(Brush)));

        // 仪表当前值属性
        public int Value
        {
            get { return (int)this.GetValue(ValueProperty); }
            set { this.SetValue(ValueProperty, value); }
        }
        // 注册仪表当前值依赖属性，提供默认值并指定属性变更回调
        public static readonly DependencyProperty ValueProperty =
            DependencyProperty.Register("Value", typeof(int), typeof(MonitoringDashboard),
                new PropertyMetadata(default(int), new PropertyChangedCallback(OnPorpertyChanged)));

        // 仪表最小值属性
        public int Minimum
        {
            get { return (int)GetValue(MinimumProperty); }
            set { SetValue(MinimumProperty, value); }
        }
        // 注册仪表最小值依赖属性，提供默认值并指定属性变更回调
        public static readonly DependencyProperty MinimumProperty =
            DependencyProperty.Register("Minimum", typeof(int), typeof(MonitoringDashboard),
                new PropertyMetadata(default(int), new PropertyChangedCallback(OnPorpertyChanged)));

        // 仪表最大值属性
        public int Maximum
        {
            get { return (int)GetValue(MaximumProperty); }
            set { SetValue(MaximumProperty, value); }
        }
        // 注册仪表最大值依赖属性，提供默认值并指定属性变更回调
        public static readonly DependencyProperty MaximumProperty =
            DependencyProperty.Register("Maximum", typeof(int), typeof(MonitoringDashboard),
                new PropertyMetadata(default(int), new PropertyChangedCallback(OnPorpertyChanged)));

        // 刻度间隔属性
        public int Interval
        {
            get { return (int)GetValue(IntervalProperty); }
            set { SetValue(IntervalProperty, value); }
        }
        // 注册刻度间隔依赖属性，提供默认值并指定属性变更回调
        public static readonly DependencyProperty IntervalProperty =
            DependencyProperty.Register("Interval", typeof(int), typeof(MonitoringDashboard),
                new PropertyMetadata(default(int), new PropertyChangedCallback(OnPorpertyChanged)));

        // 刻度文字大小属性
        public int ScaleTextSize
        {
            get { return (int)GetValue(ScaleTextSizeProperty); }
            set { SetValue(ScaleTextSizeProperty, value); }
        }
        // 注册刻度文字大小依赖属性，提供默认值并指定属性变更回调
        public static readonly DependencyProperty ScaleTextSizeProperty =
            DependencyProperty.Register("ScaleTextSize", typeof(int), typeof(MonitoringDashboard),
                new PropertyMetadata(default(int), new PropertyChangedCallback(OnPorpertyChanged)));

        // 刻度线画刷属性
        public Brush ScaleBrush
        {
            get { return (Brush)GetValue(ScaleBrushProperty); }
            set { SetValue(ScaleBrushProperty, value); }
        }
        // 注册刻度线画刷依赖属性，提供默认值并指定属性变更回调
        public static readonly DependencyProperty ScaleBrushProperty =
            DependencyProperty.Register("ScaleBrush", typeof(Brush), typeof(MonitoringDashboard),
                new PropertyMetadata(default(Brush), new PropertyChangedCallback(OnPorpertyChanged)));

        // 当任何依赖属性变更时调用的静态方法
        public static void OnPorpertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            // 转换为当前控件实例并调用刷新方法
            //(d as MonitoringDashboard)?.Refresh();
            if (d is MonitoringDashboard dashboard)
            {
                dashboard.Refresh();
            }
            else
            {
                // 记录日志或处理异常情况
                Debug.WriteLine($"Error: Expected MonitoringDashboard but got {d.GetType().Name}");
            }
        }


        // 刷新仪表显示的方法
        private void Refresh()
        {
            // 计算仪表半径
            double radius = this.backEllipse.Width / 2;
            // 如果半径为NaN则退出
            if (double.IsNaN(radius)) return;

            // 清空画布上的所有元素
            this.mainCanvas.Children.Clear();

            // 计算每个单位值对应的角度（270度范围）
            double step = 270.0 / (this.Maximum - this.Minimum);

            // 绘制小刻度线
            for (int i = 0; i < this.Maximum - this.Minimum; i++)
            {
                Line lineScale = new Line();
                // 计算刻度线起点坐标（使用三角函数在圆弧上定位）
                lineScale.X1 = radius - (radius - 13) * Math.Cos((i * step - 45) * Math.PI / 180);
                lineScale.Y1 = radius - (radius - 13) * Math.Sin((i * step - 45) * Math.PI / 180);
                // 计算刻度线终点坐标
                lineScale.X2 = radius - (radius - 8) * Math.Cos((i * step - 45) * Math.PI / 180);
                lineScale.Y2 = radius - (radius - 8) * Math.Sin((i * step - 45) * Math.PI / 180);

                // 设置刻度线样式
                lineScale.Stroke = this.ScaleBrush;
                lineScale.StrokeThickness = 1;

                // 将刻度线添加到画布
                this.mainCanvas.Children.Add(lineScale);
            }

            // 计算大刻度间隔对应的角度
            step = 270.0 / Interval;
            int scaleText = this.Minimum;
            // 绘制大刻度线和刻度值
            for (int i = 0; i <= Interval; i++)
            {
                Line lineScale = new Line();
                // 计算大刻度线起点坐标
                lineScale.X1 = radius - (radius - 20) * Math.Cos((i * step - 45) * Math.PI / 180);
                lineScale.Y1 = radius - (radius - 20) * Math.Sin((i * step - 45) * Math.PI / 180);
                // 计算大刻度线终点坐标
                lineScale.X2 = radius - (radius - 8) * Math.Cos((i * step - 45) * Math.PI / 180);
                lineScale.Y2 = radius - (radius - 8) * Math.Sin((i * step - 45) * Math.PI / 180);

                // 设置大刻度线样式
                lineScale.Stroke = this.ScaleBrush;
                lineScale.StrokeThickness = 1;

                // 将大刻度线添加到画布
                this.mainCanvas.Children.Add(lineScale);

                // 创建刻度值文本块
                TextBlock textScale = new TextBlock();
                textScale.Width = 34;
                textScale.TextAlignment = TextAlignment.Center;
                textScale.FontSize = this.ScaleTextSize;
                // 计算并设置刻度值
                textScale.Text = (scaleText + (this.Maximum - this.Minimum) / Interval * i).ToString();

                // 设置文本样式
                textScale.Foreground = this.ScaleBrush;
                // 计算并设置文本位置
                Canvas.SetLeft(textScale, radius - (radius - 36) * Math.Cos((i * step - 45) * Math.PI / 180) - 17);
                Canvas.SetTop(textScale, radius - (radius - 36) * Math.Sin((i * step - 45) * Math.PI / 180) - 10);

                // 将文本添加到画布
                this.mainCanvas.Children.Add(textScale);
            }

            // 定义并设置仪表背景圆形路径
            string sData = "M{0} {1} A{0} {0} 0 1 1 {1} {2}";
            sData = string.Format(sData, radius / 2, radius, radius * 1.5);
            var converter = TypeDescriptor.GetConverter(typeof(Geometry));
            this.circle.Data = (Geometry)converter.ConvertFrom(sData);

            // 计算指针旋转角度
            step = 270.0 / (this.Maximum - this.Minimum);
            // 创建指针旋转动画，使指针平滑移动到新位置
            DoubleAnimation da = new DoubleAnimation((int)((this.Value - this.Minimum) * step) - 45, new Duration(TimeSpan.FromMilliseconds(200)));
            this.rtPointer.BeginAnimation(RotateTransform.AngleProperty, da);

            // 定义并设置指针形状
            sData = "M{0} {1},{1} {2},{1} {3}";
            sData = string.Format(sData, radius * 0.3, radius, radius - 5, radius + 5);
            this.pointer.Data = (Geometry)converter.ConvertFrom(sData);
           
        }
    }
}
